//
//
// brief	连接设备管理
// author	云
// desc:	连接设备管理 map[device-worker]
// date:	2017-02-07
// version:	v0.9
//
//

package worker

import (
	"io/ioutil"
	"encoding/json"
	"errors"
)

type ServiceCell struct {
	Id 		string		`json:"id"`
	Type 	string		`json:"type"`
}

// 设备状态信息描述
const (
	DEV_ST_ONLINE	= "online"
	DEV_ST_OFFLINE = "offline"

	// 设备配置文件路径
	DEV_CFG_FILE = "conf/devices.json"
)



//
// 设备基本描述信息
//
type Device struct {
	Name 	string		`json:"name"`
	Id 		string		`json:"id"`
	Key 	string		`json:"key"`
	Desc	string		`json:"desc"`

	Software 	string		`json:"saftware"`
	Hardware 	string		`json:"hardware"`
	Family 	 	string		`json:"family"`

	State 		string		`json:"state"`

	Services	[]ServiceCell	`json:"services"`
}

//
// 设备服务列表,一定是在线设备
//
type DeviceServices struct {
	// 服务列表指向的设备
	dev     	*Device

	// 设备连接的接待
	worker  	*Worker

	// 根据dev.Services初始化的一张服务列表
	// map[sevId: string] Service
	SevMaps 	map[string]SevInterface
}

//
// 设备列表
//
var DeviceList 	[]Device = func() []Device {
	var dev []Device = nil

	buf, err := ioutil.ReadFile(DEV_CFG_FILE)
	if err != nil {
		return dev
	}

	json.Unmarshal(buf, &dev)

	return dev
}()

//
// 通过设备ID查找对于的设备
//
func FindDevice(id string) *Device  {
	for _, dev := range DeviceList {
		if dev.Id == id {
			return &dev
		}
	}
	return nil
}

//
// 在线设备列表
//
var DeviceOnlineList map[string]DeviceServices = func() map[string]DeviceServices {
	return make(map[string]DeviceServices)
}()

//
// 设备在线
// devId: 设备ID
// w: 远程设备连接的接待者
// dev_sevs: 设备与服务表单
//
func DeviceOnline(devId string, w *Worker) *DeviceServices {

	// 找到对应的设备
	dev := FindDevice(devId)
	if dev == nil {
		return nil
	}

	dev_sevs := DeviceServices{
		dev: dev,
		worker: w,
	}

	dev_sevs.SevMaps = make(map[string]SevInterface)
	// 初始化服务实例
	for _, sev := range dev.Services {
		var sev_t SevInterface

		// 实例化服务
		if sev.Type == SEV_SWITCH_TYPE {
			sev_t = NewSwitch(sev.Id, w.post, w.notify)
		} else if sev.Type == SEV_TEMP_TYPE {
			sev_t = NewTemp(sev.Id, w.post, w.notify)
		}

		//
		if sev_t == nil {
			evtLogger.Info("device online err ------%s------", sev.Id)
		}

		dev_sevs.SevMaps[sev.Id] = sev_t
	}

	//
	// 长连接断开通过设备间的心跳判断
	// 在上一条连接服务端还没有检测到断开之前，设备又再次发起登陆请求
	// 应该将上一条连接销毁,然后将新的连接保存的列表里面
	//
	if dev, ok := DeviceOnlineList[devId]; ok {
		dev.worker.Destroy()
	}

	// 将设备加入设备在线列表中
	DeviceOnlineList[devId] = dev_sevs

	return &dev_sevs
}

//
// 设备离线
//
func DeviceOffline(devId string, w *Worker) error {
	if devId == "" {
		return errors.New("404")
	}

	if dev, ok := DeviceOnlineList[devId]; ok {
		if dev.worker == w {
			delete(DeviceOnlineList, devId)
			return nil
		}
	}

	return errors.New("404")
}


//
// 外接对设备的操作请求
//
func RequestDevice(buffer []byte) error {
	var request Request

	err := json.Unmarshal(buffer, &request)
	if err != nil {
		return err
	}

	if request.DevId == "" {
		return err
	}

	// 在在线设备里面查找
	if dev, ok := DeviceOnlineList[request.DevId]; ok {
		dev.worker.Request(buffer)
	}

	return nil
}

//
// 设备产生的通知消息加工处理
//
func DeviceNotify(devId string, notify []byte) error {
	if devSubscribeHandle != nil {
		return devSubscribeHandle.Notify(notify)
	}
	return nil
}

//
// 设备消息订阅接口
//
type DevSubscribeInterface interface {
	Notify(buffer []byte)  (err error)
}

// 设备接口消息订阅
var devSubscribeHandle DevSubscribeInterface = nil

//
// 订阅通知消息
//
func SubScribeNotify(i DevSubscribeInterface) error {
	err := errors.New("404")
	if i != nil {
		devSubscribeHandle = i
		return nil
	}
	return err
}

